package com.donglan.pethome.order.service.impl;

import com.donglan.pethome.basic.util.CodeGenerateUtils;
import com.donglan.pethome.order.domain.OrderAddress;
import com.donglan.pethome.order.domain.OrderAdopt;
import com.donglan.pethome.order.domain.UserAddress;
import com.donglan.pethome.order.mapper.OrderAddressMapper;
import com.donglan.pethome.order.mapper.OrderAdoptMapper;
import com.donglan.pethome.order.mapper.UserAddressMapper;
import com.donglan.pethome.order.service.OrderAdoptService;
import com.donglan.pethome.pay.constant.PayConstants;
import com.donglan.pethome.pay.domain.PayBill;
import com.donglan.pethome.pay.mapper.PayBillMapper;
import com.donglan.pethome.pay.service.PayBillService;
import com.donglan.pethome.pet.domain.Pet;
import com.donglan.pethome.pet.mapper.PetMapper;
import com.donglan.pethome.quartz.domain.QuartzJobInfo;
import com.donglan.pethome.quartz.service.QuartzService;
import com.donglan.pethome.user.domain.User;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: zhangdonghui
 * @Date: 2022/2/23 11:25
 */
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class OrderAdoptServiceImpl implements OrderAdoptService {

    // 用户地址mapper
    @Autowired
    private UserAddressMapper userAddressMapper;
    // 订单地址mapper
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    // 宠物mapper
    @Autowired
    private PetMapper petMapper;
    // 领养订单mapper
    @Autowired
    private OrderAdoptMapper orderAdoptMapper;
    // 支付单mapper
    @Autowired
    private PayBillMapper payBillMapper;
    // 支付单service
    @Autowired
    private PayBillService payBillService;
    // 定时器service
    @Autowired
    private QuartzService quartzService;

    /*
     * 功能描述 提交订单
     * @author zhangdonghui
     * @date 2022/2/23 12:09
     * @param map 前端传递的参数
     * @param user 当前的登录用户
     * @return void
     */
    @Override
    @Transactional
    public String saveOrderAdopt(Map<String, Object> map, User user) {
        // 用户地址id
        String addressId = map.get("addressId").toString();
        // 通过用户地址id，获取用户地址对象
        // 用户地址中有很多收货地址，我们需要获取收货地址放到订单地址里面
        UserAddress userAddress = userAddressMapper.loadById(Long.valueOf(addressId));
        // 把用户地址转换为订单地址
        OrderAddress orderAddress = userAddressToOrderAddress(userAddress);
        // 设置订单编号
        orderAddress.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        // 保存订单地址
        orderAddressMapper.add(orderAddress);

        // 宠物id
        String petId = map.get("petId").toString();
        Pet pet = petMapper.loadById(Long.valueOf(petId));
        // 保存领养订单
        OrderAdopt orderAdopt = createOrderAdopt(pet,orderAddress,user);
        orderAdoptMapper.add(orderAdopt);
        // 修改pet宠物表的数据
        pet.setShop(null);
        pet.setUser(user);
        pet.setOffsaletime(new Date());
        pet.setState(0);
        petMapper.update(pet);

        // 获取前端的支付方式数据
        Integer payType = Integer.valueOf(map.get("payType").toString());
        // 创建支付订单
        PayBill payBill = createPayBill(orderAdopt,payType);
        payBillMapper.add(payBill);
        // 跳转到支付页面
        // 查看支付类型，如果是微信的，需要跳转到微信的支付界面，
        // 支付宝的需要跳转到支付宝支付界面，所以使用switch
        // 但是这里我们就省掉，直接使用支付宝支付界面
        String payBillHtml = payBillService.goPay(orderAdopt);
        //System.out.println(payBillHtml);
        // 开启定时器
        QuartzJobInfo quartzJobInfo = createQuartzJobInfo(orderAdopt);
        // 添加任务
        quartzService.addJob(quartzJobInfo);
        return payBillHtml;
    }

    /*
     * 功能描述 添加 QuartzJobInfo 对象
     * @author zhangdonghui
     * @date 2022/3/18 21:48
     * @param orderAdopt 领养订单对象
     * @return com.donglan.pethome.quartz.domain.QuartzJobInfo
     */
    private QuartzJobInfo createQuartzJobInfo(OrderAdopt orderAdopt) {
        QuartzJobInfo info = new QuartzJobInfo();
        // 定时任务最终目标：如果15分钟后未支付，需要把订单状态和支付状态改成 -1
        // 我需要去操作订单，那么我需要知道操作哪张订单
        // 在这里记录一个类型，我们之前写好的常量
        // com\donglan\pethome\pay\constant\PayConstants.java类中
        // 当前我们是再领养订单中，所以使用如下常量
        // 设置type的最终目的：记录到时候定时器操作指定的订单表
        info.setType(PayConstants.BUSINESSTYPE_ADOPT);
        info.setFireDate(orderAdopt.getLastPayTime());// 设置最后支付时间
        // 任务名称保持唯一
        info.setJobName(PayConstants.BUSINESSTYPE_ADOPT + orderAdopt.getOrderSn());
        // 添加需要传递的参数，关联的键值对信息
        Map<String,Object> params = new HashMap<>();
        params.put("orderSn",orderAdopt.getOrderSn());// 方便获取支付单对象
        params.put("shopId",orderAdopt.getShop().getId());// 方便宠物恢复店铺
        params.put("petId",orderAdopt.getPet().getId());// 方便获取宠物对象
        info.setParams(params);
        return info;
    }

    /*
     * 功能描述 创建支付单
     * @author zhangdonghui
     * @date 2022/3/2 17:43
     * @param orderAdopt    领养订单
     * @param payType   支付类型
     * @return com.donglan.pethome.pay.domain.PayBill
     */
    private PayBill createPayBill(OrderAdopt orderAdopt,Integer payType) {
        PayBill payBill = new PayBill();
        // 摘要
        payBill.setDigest("【领养订单】对"+orderAdopt.getPet().getName()+"萌宠进行领养");
        // 交易金额
        payBill.setMoney(orderAdopt.getPrice());
        // 支付单的支付时间是领养订单支付时间
        payBill.setLastPayTime(orderAdopt.getLastPayTime());
        // 支付方式，从前端获取的支付方式，我们是写死的
        payBill.setPayChannel(payType);
        // 添加订单号
        payBill.setOrderSn(orderAdopt.getOrderSn());
        // 用户
        payBill.setUser(orderAdopt.getUser());
        // 店铺
        payBill.setShop(orderAdopt.getShop());
        payBill.setNickName(orderAdopt.getUser().getUsername());
        // 业务类型，设置常量，毕竟就那几个表
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_ADOPT);
        // 业务键 定位表中的具体哪条数据
        payBill.setBusinessKey(orderAdopt.getId());
        return payBill;
    }

    /*
     * 功能描述 创建领养订单
     * @author zhangdonghui
     * @date 2022/2/23 14:47
     * @param [领养的宠物, 订单地址对象,当前登录用户]
     * @return com.donglan.pethome.order.domain.OrderAdopt
     */
    private OrderAdopt createOrderAdopt(Pet pet,OrderAddress orderAddress,User user) {
        OrderAdopt orderAdopt = new OrderAdopt();
        orderAdopt.setDigest("【摘要】对"+pet.getName()+"的进行领养");
        // 当前时间 + 15分钟  在转换成Date对象  最后支付时间
        // 提交订单之后的15分钟内，必须完成支付，否则取消
        //Date date = new Date(new Date().getTime() + 15 * 60 * 1000);
        //Date lastPayTime = DateUtils.addMinutes(new Date(), 15);
        Date lastPayTime = DateUtils.addSeconds(new Date(), 15);
        // 设置最后支付时间
        orderAdopt.setLastPayTime(lastPayTime);
        // 设置金额
        orderAdopt.setPrice(pet.getSaleprice());
        // 设置订单编号
        orderAdopt.setOrderSn(orderAddress.getOrderSn());
        // 设置领养的宠物
        orderAdopt.setPet(pet);
        // 设置买家用户
        orderAdopt.setUser(user);
        // 设置卖家店铺
        orderAdopt.setShop(pet.getShop());

        return orderAdopt;
    }

    /*
     * 功能描述 把用户地址转换为订单地址
     * @author zhangdonghui
     * @date 2022/2/23 12:03
     * @param userAddress
     * @return com.donglan.pethome.order.domain.OrderAddress
     */
    private OrderAddress userAddressToOrderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        orderAddress.setCreateTime(new Date());
        System.out.println(orderAddress);
        return orderAddress;
    }
}
